﻿using System;
using System.Collections.Generic;
using System.Web;
using System.Data;
using System.Configuration;
using System.IO;
using System.Globalization;
using System.Collections;
using Telerik.Web.UI;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Diagnostics;


namespace Utility
{
    /// <summary>
    /// CbmUtils.cs
    /// more goble function added to here
    /// jzhao created 02/24/2011 
    /// </summary>
    public static class CbmUtils
    {
        static Type[] m_NumericTypes;
        static Type[] m_IntegerTypes;
        static Type[] m_StringTypes;
        static DbType[] m_StringDbTypes;
        static NumberFormatInfo m_DecimalFormatProvider;
        static NumberFormatInfo m_SpecialFormatProvider;

        static CbmUtils()
        {
            m_NumericTypes = new Type[] { typeof(byte), typeof(sbyte), typeof(short), typeof(int), typeof(long), typeof(ushort), typeof(uint), typeof(ulong), typeof(float), typeof(double), typeof(decimal) };
            m_IntegerTypes = new Type[] { typeof(byte), typeof(sbyte), typeof(short), typeof(int), typeof(long), typeof(ushort), typeof(uint), typeof(ulong) };
            m_StringTypes = new Type[] { typeof(string), typeof(char) };
            DbType[] typeArray2 = new DbType[4];
            typeArray2[1] = DbType.AnsiStringFixedLength;
            typeArray2[2] = DbType.String;
            typeArray2[3] = DbType.StringFixedLength;
            m_StringDbTypes = typeArray2;
            m_DecimalFormatProvider = null;
            m_SpecialFormatProvider = null;

        }

        public static bool HtmlToPdfFile(string strPath, string URL, string strFileName)
        {
            if (URL.Length > 0 && strFileName.Length > 0)
            {
                ProcessStartInfo info = new ProcessStartInfo
                {
                    CreateNoWindow = true,
                    WindowStyle = ProcessWindowStyle.Hidden,
                    WorkingDirectory = Path.Combine(strPath, "Bin"),
                    Arguments = string.Format("{0} {1}", URL, strFileName),
                    FileName = Path.Combine(Path.Combine(strPath, "Bin"), "HtmlToPdf.exe")
                };

                Process process = new Process
                {
                    StartInfo = info
                };
                process.Start();
                process.WaitForExit(0x7fffffff);

                return true;
            }


            return true;
        }

        public static DataView CreateDataView(DataTable dt, string filter)
        {
            return new DataView(dt, filter, "", DataViewRowState.CurrentRows);
        }

        public static string GetAppConfig(string key, string defValue)
        {
            return Nvl(ConfigurationManager.AppSettings.Get(key), defValue);
        }

        public static bool IsNull(object obj)
        {
            return (obj == null || Convert.IsDBNull(obj));
        }

        public static bool IsEmpty(string s)
        {
            return (string.IsNullOrEmpty(s));
        }

        public static bool IsEmpty(object o)
        {
            return (IsNull(o) || IsEmpty(o.ToString()));
        }

        public static bool IsNumber(DataColumn column)
        {
            return CbmUtils.IsNumber(column.DataType);
        }

        public static bool IsNumber(Type aType)
        {
            return (Array.IndexOf<Type>(m_NumericTypes, aType) >= 0);
        }

        public static bool IsInteger(DataColumn column)
        {
            return IsInteger(column.DataType);
        }

        public static bool IsInteger(Type aType)
        {
            return (Array.IndexOf<Type>(m_IntegerTypes, aType) >= 0);
        }

        public static bool IsDateTime(DataColumn column)
        {
            return CbmUtils.IsDateTime(column.DataType);
        }

        public static bool IsDateTime(Type aType)
        {
            return (aType == typeof(DateTime));
        }

        public static bool IsBoolean(DataColumn column)
        {
            return CbmUtils.IsBoolean(column.DataType);
        }

        public static bool IsBoolean(Type aType)
        {
            return (aType == typeof(bool));
        }

        public static bool IsGuid(DataColumn column)
        {
            return CbmUtils.IsGuid(column.DataType);
        }

        public static bool IsGuid(Type aType)
        {
            return (aType == typeof(Guid));
        }

        public static bool IsBinary(DataColumn column)
        {
            return CbmUtils.IsBinary(column.DataType);
        }

        public static bool IsBinary(Type aType)
        {
            return (aType == typeof(byte[]));
        }

        public static bool IsString(DataColumn column)
        {
            return (CbmUtils.IsString(column.DataType) && column.MaxLength < int.MaxValue);
        }

        public static bool IsString(DbType dbType)
        {
            return (Array.IndexOf<DbType>(m_StringDbTypes, dbType) >= 0);
        }

        public static bool IsString(Type aType)
        {
            return (Array.IndexOf<Type>(m_StringTypes, aType) >= 0);
        }

        public static bool IsLong(DataColumn column)
        {
            return (CbmUtils.IsString(column.DataType) && column.MaxLength == int.MaxValue);
        }

        public static DateTime MaxDateTime(DateTime d1, DateTime d2)
        {
            return ((d1 > d2) ? d1 : d2);
        }

        public static DateTime MinDateTime(DateTime d1, DateTime d2)
        {
            return ((d1 < d2) ? d1 : d2);
        }


        public static void ClearDataTable(DataTable dt)
        {
            if (dt != null)
            {
                dt.BeginLoadData();
                try
                {
                    dt.Rows.Clear();
                }
                finally
                {
                    dt.EndLoadData();
                }
            }
        }

        public static object GetFieldValue(DataRow row, string fieldName, object defValue)
        {
            object result = defValue;
            if (row != null && row.Table != null)
            {
                int index = row.Table.Columns.IndexOf(fieldName);
                if (index >= 0)
                {
                    result = row[index];
                }
            }
            return result;
        }

        public static string GetFieldValue(DataRow row, string fieldName, string defValue)
        {
            string result = defValue;
            if (row != null && row.Table != null)
            {
                int index = row.Table.Columns.IndexOf(fieldName);
                if (index >= 0)
                {
                    result = row[fieldName].ToString();
                }
            }
            return result;
        }

        public static string GetFieldValue(DataRow row, string fieldName)
        {
            return GetFieldValue(row, fieldName, "");
        }

        public static bool IsEmptyOrZero(object o)
        {
            if (IsNull(o)) return true;

            var type = o.GetType();
            if (IsNumber(type))
                return Convert.ChangeType(0, type).Equals(o);

            return IsString(type) && o.Equals("");
        }

        public static bool NotEmpty(string s)
        {
            return (!IsEmpty(s));
        }

        public static bool NotEmpty(object o)
        {
            return (!IsEmpty(o));
        }

        public static string Nvl(string s)
        {
            return Nvl(s, "");
        }

        public static string Nvl(string s, string defaultValue)
        {
            return (IsEmpty(s) ? defaultValue : s);
        }

        public static object Nvl(object obj, object defaultValue)
        {
            return (IsNull(obj) ? defaultValue : obj);
        }




        public static int ParseInt(string s, int defValue)
        {
            if (IsEmpty(s)) return defValue;
            try
            {
                return Int32.Parse(s.Trim());
            }
            catch
            {
                return defValue;
            }
        }

        public static Decimal ParseDecimal(string s, Decimal defValue)
        {
            if (IsEmpty(s)) return defValue;
            try
            {
                return Decimal.Parse(s.Trim());
            }
            catch (Exception)
            {
                return defValue;
            }
        }

        public static Decimal ParseDecimalConstant(string s, Decimal defValue)
        {
            if (IsEmpty(s)) return defValue;
            try
            {
                return StringToDecimal(s.Trim());
            }
            catch (Exception)
            {
                return defValue;
            }
        }

        public static decimal StringToDecimal(string val)
        {
            return decimal.Parse(val, GetSpecialFormatProvider());
        }

        public static double StringToDouble(string val)
        {
            return (double)float.Parse(val, GetSpecialFormatProvider());
        }

        public static float StringToFloat(string val)
        {
            return float.Parse(val, GetSpecialFormatProvider());
        }

        public static DateTime ParseDateTime(string s)
        {
            return ParseDateTime(s, "yyyy-MM-dd HH:mm:ss.fff");
        }

        public static DateTime ParseDateTime(string s, string format)
        {
            return DateTime.ParseExact(s, format, null);
        }

        public static object StringToObject(string s, Type type)
        {
            if (type == typeof(string))
            {
                return s;
            }
            if (type == typeof(int))
            {
                return ParseInt(s, 0);
            }
            if (type == typeof(double))
            {
                return Convert.ToDouble(ParseFloat(s, 0f));
            }
            if (type == typeof(decimal))
            {
                return CbmUtils.ParseDecimal(s, 0M);
            }
            if (type == typeof(bool))
            {
                return ParseBool(s, false);
            }
            if (type == typeof(DateTime))
            {
                return ParseDateTime(s);
            }
            if (type != typeof(Guid))
            {
                throw new Exception("Type " + type.Name + " could not be storable");
            }
            return new Guid(s);
        }

        public static string Substring(string s, int start, int length)
        {
            string str = Nvl(s);
            int startIndex = Math.Min(Math.Max(0, start), str.Length);
            int num2 = Math.Max(Math.Min(length, str.Length - startIndex), 0);
            return str.Substring(startIndex, num2);
        }

        public static string Substring(string s, int length)
        {
            //if (string.IsNullOrEmpty(s) || length <= 0)
            //{
            //    return string.Empty;
            //}
            //else
            //{
            //    if (s.Length > length)
            //    {
            //        return s.Substring(0, length);
            //    }
            //}
            return CbmUtils.Substring(s, 0, length);
        }

        public static string TrimSpace(string s)
        {
            return s.Trim(new char[] { ' ', '\n', '\r', '\t' });
        }

        public static IFormatProvider GetSpecialFormatProvider()
        {
            if (m_SpecialFormatProvider == null)
            {
                m_SpecialFormatProvider = (NumberFormatInfo)NumberFormatInfo.CurrentInfo.Clone();
                m_SpecialFormatProvider.NumberDecimalSeparator = ".";
                m_SpecialFormatProvider.NumberGroupSeparator = "";
            }
            return m_SpecialFormatProvider;
        }


        public static float ParseFloat(string s, float defValue)
        {
            try
            {
                return StringToFloat(s);
            }
            catch (Exception)
            {
                return defValue;
            }
        }

        public static bool ParseBool(object o)
        {
            return ParseBool(o, false);
        }
        public static bool ParseBool(string s)
        {
            return ParseBool(s, false);
        }

        public static bool? GetBoolEx(bool value)
        {
            return (value ? true : false);
        }

        public static bool ParseBool(object o, bool? defValue)
        {
            bool? boolEx = defValue;
            if (o != null)
            {
                if (o is bool)
                {
                    boolEx = GetBoolEx((bool)o);
                }
                else if (o is string)
                {
                    boolEx = GetBoolEx(ParseBool(o.ToString(), defValue));
                }
                else if (IsInteger(o.GetType()))
                {
                    boolEx = Convert.ToBoolean(o) ? true : false;
                }
            }
            if (!boolEx.HasValue)
            {
                throw new Exception("Cannot convert \"" + ((o == null) ? "null" : o.ToString()) + "\" to Boolean");
            }
            return GetBool(boolEx, false);
        }

        public static bool ParseBool(object o, bool defValue)
        {
            return ParseBool(o, GetBoolEx(defValue));
        }

        public static bool ParseBool(string s, bool? defValue)
        {
            bool? boolEx = defValue;
            if (s != null)
            {
                switch (s.ToUpper())
                {
                    case "Y":
                    case "YES":
                    case "TRUE":
                    case "T":
                    case "1":
                        boolEx = true;
                        break;

                    case "N":
                    case "NO":
                    case "FALSE":
                    case "F":
                    case "0":
                        boolEx = false;
                        break;
                }
            }
            if (!boolEx.HasValue)
            {
                throw new Exception("Cannot convert \"" + s + "\" to Boolean");
            }
            return GetBool(boolEx, false);
        }

        public static bool ParseBool(string s, bool defValue)
        {
            return ParseBool(s, GetBoolEx(defValue));
        }

        public static bool GetBool(bool? value, bool initialValue)
        {
            if (value.HasValue)
            {
                return value.Value;
            }
            else
            {
                return initialValue;
            }
        }

        public static bool GetDBValueBool(object value)
        {
            bool bRet = false;
            if (CbmUtils.NotEmpty(value))
            {
                bRet = CbmUtils.ParseBool(value.ToString());
            }
            return bRet;
        }

        public static object FindListByString(IList list, string name)
        {
            foreach (object obj in list)
            {
                if (obj.ToString() == name)
                {
                    return obj;
                }
            }
            return null;
        }

        public static object FindListByStringIgnoreCase(IList list, string name)
        {
            string upName = name.ToUpper();
            foreach (object obj in list)
            {
                if (obj.ToString().ToUpper() == upName)
                {
                    return obj;
                }
            }
            return null;
        }

        public static string GetFileAsString(string fileName)
        {
            StreamReader reader = File.OpenText(fileName);
            string s = reader.ReadToEnd();
            reader.Close();
            return s;
        }

        public static void WriteStringToFile(string fileName, string s)
        {
            using (StreamWriter sw = new StreamWriter(fileName))
            {
                sw.Write(s);
            }
        }

        public static decimal Round(decimal d, int decimals)
        {
            int num2;
            decimal num = 1M;
            for (num2 = decimals; num2 < 0; num2++)
            {
                num /= 10M;
            }
            for (num2 = 0; num2 < decimals; num2++)
            {
                num *= 10M;
            }
            decimal num3 = Math.Abs((decimal)(d * num));
            decimal num4 = Convert.ToDecimal(Math.Floor(Convert.ToDouble(num3)));
            decimal num5 = Convert.ToDecimal(Math.Ceiling(Convert.ToDouble(num3)));
            return (((((num3 - num4) < (num5 - num3)) ? num4 : num5) / num) * Math.Sign(d));
        }

        public static string GetDBValueStr(object value)
        {
            string strRet = string.Empty;
            if (CbmUtils.NotEmpty(value))
            {
                strRet = value.ToString();
            }
            return strRet;
        }

        public static DateTime? GetDBValueDate(object value)
        {
            string strRet = GetDBValueStr(value);
            DateTime? dt = null;
            if (strRet.Length > 0)
            {
                try
                {
                    dt = Convert.ToDateTime(strRet);
                }
                catch
                {
                }
            }
            return dt;
        }

        public static string GetYeNoStr(object value)
        {
            return CbmUtils.ParseBool(value) ? "Yes" : "No";
        }

        public static int GetWeekNumber(DateTime dt)
        {
            GregorianCalendar gc = new GregorianCalendar();
            return gc.GetWeekOfYear(dt, CalendarWeekRule.FirstDay, DayOfWeek.Monday);
        }

        public static int GetWeekCount(int year)
        {
            DateTime end = new DateTime(year, 12, 31);
            System.Globalization.GregorianCalendar gc = new GregorianCalendar();
            return gc.GetWeekOfYear(end, CalendarWeekRule.FirstDay, DayOfWeek.Monday);
        }

        public static DateTime GetFirstDate(DateTime date)
        {
            return Convert.ToDateTime(date.ToString("yyyy-MM-01"));
        }

        public static DateTime GetLastDate(DateTime date)
        {
            return Convert.ToDateTime(date.AddMonths(1).ToString("yyyy-MM-01")).AddDays(-1);
        }

        /// <summary>
        /// get days between two datetime Tom Zhao
        /// </summary>
        /// <param name="DateTime1">date from</param>
        /// <param name="DateTime2">date to</param>
        /// <returns></returns>
        public static int DateDiff(DateTime DateTime1, DateTime DateTime2)
        {
            int dateDiff = 0;
            TimeSpan ts1 = new TimeSpan(DateTime1.Ticks);
            TimeSpan ts2 = new TimeSpan(DateTime2.Ticks);
            TimeSpan ts = ts1.Subtract(ts2).Duration();
            dateDiff = ts.Days;
            return dateDiff;
        }


        #region Web Function
        static public Control FindControl(Control parent, string name)
        {
            Control control = parent.FindControl(name);
            if (control != null)
            {
                return control;
            }
            foreach (Control child in parent.Controls)
            {
                if (!(child is RadioButtonList))
                {
                    control = FindControl(child, name);
                    if (control != null) return control;
                }
            }
            return null;
        }
        #endregion

        #region Calc datatable col

        public static decimal CalculateDataColumnSum(DataTable table, string columnName)
        {
            return CalculateDataColumnSum(table.DefaultView, columnName);
        }
        public static decimal CalculateDataColumnSum(DataView dataView, string columnName)
        {
            decimal num = 0M;
            foreach (DataRowView view in dataView)
            {
                num += Convert.ToDecimal(Nvl(view[columnName], 0));
            }
            return num;
        }
        public static decimal CalculateDataColumnMin(DataView dataView, string columnName)
        {
            decimal num = 79228162514264337593543950335M;
            foreach (DataRowView view in dataView)
            {
                num = Math.Min(num, Convert.ToDecimal(Nvl(view[columnName], 79228162514264337593543950335M)));
            }
            return num;
        }
        public static decimal CalculateDataColumnMin(DataTable table, string columnName)
        {
            return CalculateDataColumnMin(table.DefaultView, columnName);
        }
        public static decimal CalculateDataColumnMax(DataView dataView, string columnName)
        {
            decimal num = -79228162514264337593543950335M;
            foreach (DataRowView view in dataView)
            {
                num = Math.Max(num, Convert.ToDecimal(Nvl(view[columnName], -79228162514264337593543950335M)));
            }
            return num;
        }
        public static decimal CalculateDataColumnMax(DataTable table, string columnName)
        {
            return CalculateDataColumnMax(table.DefaultView, columnName);
        }

        #endregion

        #region FillRadCmbByDt: fill RadComboBox with DataTable, also added 'All' item at first row.

        /*
    public static void FillRadCmbByDt(RadComboBox ctl, string strSql)
    {
        FillRadCmbByDt(ctl, strSql, string.Empty, string.Empty);
    }

    public static void FillRadCmbByDt(RadComboBox ctl, string strSql, string AllText)
    {
        FillRadCmbByDt(ctl, strSql, string.Empty, AllText);
    }

    public static void FillRadCmbByDt(RadComboBox ctl, string strSql, string AllKey, string AllText)
    {
        DataTable dt = DBcbm.ExecuteDataTable(strSql,ConnString.Storelist); // changed to storelist so the new divisions will be used ("north", "South", "west")
        if (dt != null)
        {
            foreach (DataRow dr in dt.Rows)
            {
                ctl.Items.Add(new RadComboBoxItem(dr[dt.Columns.Count == 1 ? 0 : 1].ToString(), dr[0].ToString()));
            }
            if ((AllKey != null && AllKey.Length > 0) || (AllText != null && AllText.Length > 0))
            {
                ctl.Items.Insert(0, new RadComboBoxItem(AllText, AllKey));
            }
        }
    }
     */
        #endregion

    }
}